/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.base.controller;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import com.xy.biz.base.domain.bo.AttachmentBO;
import com.xy.tool.minio.domain.constant.BucketConstant;
import com.xy.tool.minio.util.MinioUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xy.lang.domain.Page;
import com.xy.lang.domain.Result;
import com.xy.lang.validation.SaveChecks;
import com.xy.lang.validation.UpdateChecks;
import com.xy.lang.validation.annotation.Validatable;

import com.xy.biz.base.domain.resp.GetAttachmentResponse;
import com.xy.biz.base.domain.req.GetAttachmentRequest;
import com.xy.biz.base.domain.req.ListAttachmentRequest;
import com.xy.biz.base.domain.req.SaveAttachmentRequest;
import com.xy.biz.base.domain.query.AttachmentQuery;
import com.xy.biz.base.domain.converter.AttachmentConverter;
import com.xy.biz.base.client.AttachmentClient;
import com.xy.biz.base.service.AttachmentService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

/**
 *
 *
 * @author wwj
 * @date 2021-4-6
 */
@Api(tags = "附件服务")
@Slf4j
@RestController
@RequestMapping("/api/base/attachment")
public class AttachmentController implements AttachmentClient {

	@Autowired
	private AttachmentService attachmentService;

	@Autowired
	private MinioUtil minioUtil;

	@Validatable(groups = {SaveChecks.class})
	@PostMapping(value = "/save")
	public Result<?> saveAttachment(@RequestBody SaveAttachmentRequest request) {
		attachmentService.saveAttachment(AttachmentConverter.toBO(request));
		return Result.success();
	}

	@Validatable(groups = {SaveChecks.class})
	@PostMapping(value = "/save_all")
	public Result<?> saveAllAttachment(@RequestBody Collection<SaveAttachmentRequest> collection) {
		attachmentService.saveAllAttachment(AttachmentConverter.toBO(collection));
		return Result.success();
	}

	@Validatable(groups = {UpdateChecks.class})
	@PostMapping(value = "/update")
	public Result<?> updateAttachment(@RequestBody SaveAttachmentRequest request) {
		attachmentService.updateAttachment(AttachmentConverter.toBO(request));
		return Result.success();
	}

	@Validatable
	@PostMapping(value = "/delete")
	public Result<?> deleteAttachment(@RequestBody GetAttachmentRequest request) {
		attachmentService.deleteAttachment(request.getAttachmentId());
		return Result.success();
	}

	@Validatable
	@PostMapping(value = "/get")
	@Override
	public Result<GetAttachmentResponse> getAttachment(@RequestBody GetAttachmentRequest request) {
		return Result.success(AttachmentConverter.toResponse(attachmentService.getAttachment(request.getAttachmentId())));
	}

	@PostMapping(value = "/list_by_ids")
	@Override
	public Result<List<GetAttachmentResponse>> listAttachmentById(@RequestBody Collection<Long> collection) {
		return Result.success(AttachmentConverter.toResponse(attachmentService.listAttachmentById(collection)));
	}

	@PostMapping(value = "/list")
	@Override
	public Result<List<GetAttachmentResponse>> listAttachment(@RequestBody ListAttachmentRequest request) {
		return Result.success(AttachmentConverter.toResponse(attachmentService.listAttachment(AttachmentConverter.toQuery(request))));
	}

	@PostMapping(value = "/count")
	@Override
	public Result<Integer> countAttachment(@RequestBody ListAttachmentRequest request) {
		return Result.success(attachmentService.countAttachment(AttachmentConverter.toQuery(request)));
	}

	@PostMapping(value = "/page")
	@Override
	public Result<Page<GetAttachmentResponse>> pageAttachment(@RequestBody ListAttachmentRequest request) {
		AttachmentQuery query = AttachmentConverter.toQuery(request);
		List<GetAttachmentResponse> list = AttachmentConverter.toResponse(attachmentService.listAttachment(query));
		int count = attachmentService.countAttachment(query);
		return Result.success(new Page<>(list, count));
	}


	@PostMapping(value = "/upload_attachment")
	public Result<?> uploadAttachment(HttpServletRequest request) {
		String bizId = request.getParameter("bizId");
		String bizType = request.getParameter("bizType");
		try {
			Part httpPostedFile = request.getPart("file");
			if (
					ObjectUtils.isEmpty(bizId) ||
					ObjectUtils.isEmpty(bizType) ||
					ObjectUtils.isEmpty(httpPostedFile)) {
				return Result.ofBadParameter();
			}
			String fileName = httpPostedFile.getSubmittedFileName();
			InputStream fileStream = httpPostedFile.getInputStream();
			String fileExt = fileName.substring(fileName.lastIndexOf("."));
			Long size = minioUtil.uploadFile(fileStream, fileName, BucketConstant.ATTACHMENT_BUCKET);
			String objectURL = minioUtil.getObjectURL(BucketConstant.ATTACHMENT_BUCKET, fileName, null);
			AttachmentBO attachmentBO = attachmentService.saveAttachment(AttachmentBO.builder()
					.bizId(Long.valueOf(bizId))
					.bizType(Integer.valueOf(bizType))
					.createTime(LocalDateTime.now())
					.deleteFlag(false)
					.fileExtension(fileExt)
					.fileName(fileName)
					.fileSize(size)
					.path(fileName)
					.updateTime(LocalDateTime.now())
					.build());
			return Result.success(GetAttachmentResponse.builder().attachmentId(attachmentBO.getAttachmentId()).url(objectURL).name(fileName).build());
		} catch (IOException e) {
			e.printStackTrace();
			return Result.fail();
		} catch (ServletException e) {
			e.printStackTrace();
			return Result.fail();
		} catch (Exception e) {
			e.printStackTrace();
			return Result.fail();
		}
	}

}
